package com.test.mina2.example.message;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

public class CmccSpicDecoder2 extends CumulativeProtocolDecoder {
	private final Charset charSet;
	private final AttributeKey CONTEXT = new AttributeKey(getClass(), "context");

	public CmccSpicDecoder2(Charset charSet) {
		this.charSet = charSet;
	}

	@Override
	protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
		Context ctx = getContext(session);
		CharsetDecoder decoder = charSet.newDecoder();
		IoBuffer ioBuffer = ctx.innerBuffer;
		String statusLine = ctx.getStatusLine();
		int matchCount = ctx.getMatchCount();
		String sender = ctx.getSender();
		String receiver = ctx.getReceiver();
		String length = ctx.getLength();
		String sms = ctx.getSms();
		int line = ctx.getLine();
		while (in.hasRemaining()) {
			byte b = in.get();
			ioBuffer.put(b);
			if (b == 10 && line < 4) {
				if (line == 0) {
					ioBuffer.flip();
					statusLine = ioBuffer.getString(matchCount, decoder);
					statusLine = statusLine.substring(0, statusLine.length() - 1);
					matchCount = 0;
					ioBuffer.clear();
					ctx.setStatusLine(statusLine);
				}
				if (line == 1) {
					ioBuffer.flip();
					sender = ioBuffer.getString(matchCount, decoder);
					sender = sender.substring(0, sender.length() - 1);
					matchCount = 0;
					ioBuffer.clear();
					ctx.setSender(sender);
				}
				if (line == 2) {
					ioBuffer.flip();
					receiver = ioBuffer.getString(matchCount, decoder);
					receiver = receiver.substring(0, receiver.length() - 1);
					matchCount = 0;
					ioBuffer.clear();
					ctx.setReceiver(receiver);
				}
				if (line == 3) {
					ioBuffer.flip();
					length = ioBuffer.getString(matchCount, decoder);
					length = length.substring(0, length.length() - 1);
					matchCount = 0;
					ioBuffer.clear();
					ctx.setLength(length);
				}
				line++;
			} else if (line == 4) {
				if (matchCount == Long.parseLong(length.split(":")[1])) {
					ioBuffer.flip();
					sms = ioBuffer.getString(matchCount, decoder);
					ctx.setSms(sms);
					ctx.setMatchCount(matchCount);
					ctx.setLine(line);
					break;
				}
			}
			ctx.setMatchCount(matchCount);
			ctx.setLine(line);
		}
		if (ctx.getLine() == 4 && Long.parseLong(ctx.getLength().split("1")[1]) == ctx.getMatchCount()) {
			SmsObject smsObject = new SmsObject();
			smsObject.setSender(sender.split(":")[1]);
			smsObject.setReceiver(receiver.split(":")[1]);
			smsObject.setMessage(sms);
			out.write(smsObject);
			ctx.reset();
			return true;
		} else {
			return false;
		}
	}

	private Context getContext(IoSession session) {
		Context ctx = (Context) session.getAttribute(CONTEXT);
		if (ctx == null) {
			ctx = new Context();
			session.setAttribute(CONTEXT, ctx);
		}

		return ctx;
	}

	private class Context {
		private final IoBuffer innerBuffer;
		private String statusLine = "";
		private String sender = "";
		private String receiver = "";
		private String length = "";
		private String sms = "";
		private int matchCount = 0;
		private int line = 0;

		public Context() {
			innerBuffer = IoBuffer.allocate(100).setAutoExpand(true);
		}

		public void reset() {
			this.innerBuffer.clear();
			this.statusLine = "";
			this.sender = "";
			this.receiver = "";
			this.length = "";
			this.sms = "";
			this.matchCount = 0;
			this.line = 0;
		}

		/**
		 * @return the statusLine
		 */
		public String getStatusLine() {
			return statusLine;
		}

		/**
		 * @param statusLine
		 *            the statusLine to set
		 */
		public void setStatusLine(String statusLine) {
			this.statusLine = statusLine;
		}

		/**
		 * @return the sender
		 */
		public String getSender() {
			return sender;
		}

		/**
		 * @param sender
		 *            the sender to set
		 */
		public void setSender(String sender) {
			this.sender = sender;
		}

		/**
		 * @return the receiver
		 */
		public String getReceiver() {
			return receiver;
		}

		/**
		 * @param receiver
		 *            the receiver to set
		 */
		public void setReceiver(String receiver) {
			this.receiver = receiver;
		}

		/**
		 * @return the length
		 */
		public String getLength() {
			return length;
		}

		/**
		 * @param length
		 *            the length to set
		 */
		public void setLength(String length) {
			this.length = length;
		}

		/**
		 * @return the sms
		 */
		public String getSms() {
			return sms;
		}

		/**
		 * @param sms
		 *            the sms to set
		 */
		public void setSms(String sms) {
			this.sms = sms;
		}

		/**
		 * @return the matchCount
		 */
		public int getMatchCount() {
			return matchCount;
		}

		/**
		 * @param matchCount
		 *            the matchCount to set
		 */
		public void setMatchCount(int matchCount) {
			this.matchCount = matchCount;
		}

		/**
		 * @return the line
		 */
		public int getLine() {
			return line;
		}

		/**
		 * @param line
		 *            the line to set
		 */
		public void setLine(int line) {
			this.line = line;
		}
	}
}
